﻿using MathNet.Numerics.LinearAlgebra;
using MathNet.Numerics.LinearAlgebra.Double;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace DataWorks_Tools.MatlabDetails
{
    public static class MatrixCal
    {
        /// <summary>
        /// 把原矩阵转为PHI形式的List<double[]>，后面再转成矩阵
        /// </summary>
        /// <param name="data"></param>
        /// <param name="CausalOrder"></param>
        /// <param name="UncausalOrder"></param>
        /// <returns></returns>
        public static List<double[]> Matrix2PHI(this Matrix<double> data, int CausalOrder, int UncausalOrder)
        {
            List<double[]> results = new List<double[]>();
            //PHI的行数
            var phirow = data.RowCount - CausalOrder - UncausalOrder + 1;
            //PHI的列数
            var phicol = data.ColumnCount * (CausalOrder + UncausalOrder);
            for (int i = 0; i < phirow; i++)
            {
                //每一次取第i行开始的CausalOrder行，第一列开始到最后一列的子矩阵，注意矩阵下标从0开始
                var submatrix = data.SubMatrix(i, CausalOrder, 0, data.ColumnCount);
                //把子矩阵转化为行向量并把行的顺序反转连成一个行数组
                var t = submatrix.EnumerateRows().Reverse().SelectMany(row => row).ToArray();
                results.Add(t);
            }
            return results;
        }

        /// <summary>
        /// 把行向量转为转为每行相同的矩阵
        /// </summary>
        /// <param name="data"></param>
        /// <param name="rows">需要的行数</param>
        /// <returns></returns>
        public static Matrix<double> VectorToMatrix(this Vector<double> data, int rows)
        {
            Matrix<double> resultMatrix = Matrix<double>.Build.Dense(rows, data.Count, (i, j) => data[j]);
            return resultMatrix;
        }
        /// <summary>
        /// 该方法用于将矩阵中前面的多行数据替换为指定行的数据。
        /// </summary>
        /// <param name="matrix">要操作的 Matrix<double> 对象</param>
        /// <param name="rowcount">行数，指定替换前面多少行数据</param>
        public static void ReplaceRowsInPlace(this Matrix<double> matrix, int rowcount)
        {
            // 获取矩阵的第 rowcount 行数据
            Vector<double> newRow = matrix.Row(rowcount - 1);
            // 将前 rowcount 行数据替换成第 rowcount 行的数据
            for (int i = 0; i < rowcount - 1; i++)
            {
                matrix.SetRow(i, newRow);
            }
        }
    }
}
